import mountElement, { createDOMElement } from './mountElement'
import updateTextNode from './vdom/updateTextNode'
import updateNodeElement from './vdom/updateNodeElement'
import unMountNode from './vdom/unMountNode'
import diffComponent from './diffComponent'

export default function diff(virtualDOM, container, oldEl) {
    let oldVirtualDOM = oldEl && oldEl._virtualDOM

    if (!oldEl) {
        mountElement(virtualDOM, container)
    } else if (virtualDOM.type !== oldVirtualDOM.type && typeof virtualDOM.type !== 'function') {
        const newEl = createDOMElement(virtualDOM)
        oldEl.parentNode.replaceChild(newEl, oldEl)
    } else if (typeof virtualDOM.type === 'function') {
        const oldComponent = oldVirtualDOM && oldVirtualDOM.component
        diffComponent(virtualDOM, oldComponent, oldEl, container)
    } else if (oldVirtualDOM && virtualDOM.type === oldVirtualDOM.type) {
        // 更新文本节点
        if (virtualDOM.type === 'text') {
            updateTextNode(virtualDOM, oldVirtualDOM, oldEl)
        } else {
            // 元素节点
            updateNodeElement(oldEl, virtualDOM, oldEl._virtualDOM)
        }

        let keys = {}
        for (let i = 0, len = oldEl.childNodes.length; i < len; i++) {
            let el = oldEl.childNodes[i]
            if (el.nodeType === 1) {
                let key = el.getAttribute("key")
                if (key) {
                    keys[key] = oldEl.childNodes[i]
                }
            }
        }

        const hasNoKey = Object.keys(keys).length === 0
        if (hasNoKey) {
            virtualDOM.children.forEach((child, index) => {
                diff(child, oldEl, oldEl.childNodes[index])
            })
        } else {
            virtualDOM.children.forEach((child, i) => {
                const key = child.props.key
                if (key) {
                    let oldDOM = keys[key]
                    // debugger
                    if (oldDOM) {
                        if (oldEl.childNodes[i] && oldEl.childNodes[i] !== oldDOM) {
                            oldEl.insertBefore(oldDOM, oldEl.childNodes[i])
                        }
                    } else {
                        mountElement(child, oldEl, oldEl.childNodes[i])
                    }
                }
            })
        }

        // 删除多余节点
        if (oldEl.childNodes.length > virtualDOM.children.length) {
            if (hasNoKey) {
                for (let i = oldEl.childNodes.length - 1; i > virtualDOM.children.length - 1; i++) {
                    unMountNode(oldEl.childNodes[i])
                }
            } else {
                for (let i = 0, len = oldEl.childNodes.length; i < len; i++) {
                    const oldChild = oldEl.childNodes[i]
                    const key = oldChild._virtualDOM.props.key
                    let notFound = !virtualDOM.children.find(child => key === child.props.key)
                    if(notFound){
                        unMountNode(oldChild)
                    }
                }
            }
        }
    }
}
